package com.topisv.tms.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.BackupTask;
import com.topisv.tms.entity.BackupTaskOrdeno;
import com.topisv.tms.entity.BackupTaskSku;
import com.topisv.tms.entity.BatchTask;
import com.topisv.tms.entity.CusStockMerge;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.ShippedBatch;
import com.topisv.tms.entity.ShippedBox;
import com.topisv.tms.entity.ShippedBoxSkus;
import com.topisv.tms.entity.stock.CusStock;
import com.topisv.tms.entity.work.WorkTaskItem;
import com.topisv.tms.entity.work.ExceptionOrder.ExceptionOrder;
import com.topisv.tms.repository.BackupTaskDao;
import com.topisv.tms.repository.BackupTaskOrdenoDao;
import com.topisv.tms.repository.BackupTaskSkuDao;
import com.topisv.tms.repository.BatchTaskDao;
import com.topisv.tms.repository.CusStockMergeDao;
import com.topisv.tms.repository.CustomersDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.EdiOrderItemDao;
import com.topisv.tms.repository.ShippedBatchDao;
import com.topisv.tms.repository.ShippedBoxDao;
import com.topisv.tms.repository.ShippedBoxOrdenoDao;
import com.topisv.tms.repository.ShippedBoxSkusDao;
import com.topisv.tms.repository.stock.CusStockDao;
import com.topisv.tms.repository.work.WorkTaskItemDao;
import com.topisv.tms.repository.work.ExceptionOrder.ExceptionOrderDao;
import com.topisv.tms.utils.http.HttpPost;

@Component
@Transactional(readOnly = true)
public class BackupTaskOrdenoService {
	private static final Logger log = LoggerFactory.getLogger(BackupTaskOrdenoService.class);
	
	
	@Autowired
	private BackupTaskOrdenoDao backupTaskOrdenoDao;
	@Autowired
	private EdiOrderDao ediOrderDao;
	@Autowired
	private EdiOrderItemDao ediOrderItemDao;
	@Autowired
	private BackupTaskSkuDao backupTaskSkuDao;
	@Autowired
	private BackupTaskDao backupTaskDao;
	@Autowired
	private BatchTaskDao batchTaskDao;
	@Autowired
	private ShippedBatchDao shippedBatchDao;
	@Autowired
	private ShippedBoxDao shippedBoxDao;
	@Autowired
	private ShippedBoxSkusDao shippedBoxSkusDao;
	@Autowired
	private ShippedBoxOrdenoDao shippedBoxOrdenoDao;
	@Autowired
	private EdiOrderService ediOrderService;
	@Autowired
	private CustomersDao customersDao;
	@Autowired
	private WorkTaskItemDao workTaskItemDao;
	@Autowired
	private ExceptionOrderDao exceptionOrderDao;
	@Autowired
	private CusStockMergeDao cusStockMergeDao;
	@Autowired
	private CusStockDao cusStockDao;
	
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	private void setShippedBox(String boxCode)throws Exception{
		try {
			int skuQty=0;
			List<ShippedBoxSkus> shippedBoxSkus=shippedBoxSkusDao.findByBoxCode(boxCode);
			for(ShippedBoxSkus s:shippedBoxSkus){
				skuQty+=s.getRealQty();
			}
			if(skuQty>0){
				ShippedBox shippedBox=shippedBoxDao.findByBoxCode(boxCode);
				shippedBox.setSkuQty(skuQty);
				shippedBoxDao.save(shippedBox);
			}
		
		} catch (Exception e) {
			throw e;
		}
	}
	
	@Transactional(readOnly = false, rollbackFor = Exception.class)
    private void updateStock(BackupTaskOrdeno bto,String customerCode,String warehouseCode) throws Exception {
		  try {
			  String stockInfo,stockCode,boxCode,sku;
			    Integer num;
			    String[] stockInfoSplit;
			    String[] infoSplit;
			    CusStock stock;
				stockInfo=bto.getStockInfo();
				stockInfoSplit=stockInfo.split(";");
				for (String info : stockInfoSplit) {
					infoSplit=info.split("_");
					stockCode=infoSplit[0];
					boxCode=infoSplit[1];
					sku=infoSplit[2];
					num=Integer.valueOf( infoSplit[3] );
					stock=this.cusStockDao.loadStock(customerCode, warehouseCode, stockCode, boxCode, sku);
					int number=(stock.getOrderNum()-num>0)?(stock.getOrderNum()-num):0;
					stock.setOrderNum(number);
					this.cusStockDao.save(stock);
				}
		} catch (Exception e) {
			throw e;
		}
	}
	

	
	/**
	 * WMS集发取消订单
	 * @param ordeno
	 * @throws Exception
	 */
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	public void cancelOrdeno(String ordeno,String customerCode,String jobuuid)throws Exception {
     	EdiOrder e=null;
		try {
			Customers customers=this.customersDao.findByCustomerCode(customerCode);
			if(customers==null){
				throw new Exception("客户编码："+customerCode+"不存在");
			}
			log.info("开始取消订单---订单号:"+ordeno+"====客户:"+customers.getCustomerName());
			Map<String, Object> filterParams=new HashMap<String, Object>();
			filterParams.put("EQ_customerCode", customerCode);
			filterParams.put("EQ_ordeno", ordeno);
			List<EdiOrder> ediOrders=this.ediOrderService.crTimeHoursLists(filterParams);
			if(ediOrders.isEmpty()){
				filterParams.remove("EQ_ordeno");
				filterParams.put("LIKE_customerOrdeno", ordeno);
				ediOrders=this.ediOrderService.crTimeHoursLists(filterParams);
				if(ediOrders.isEmpty()){
					filterParams.remove("LIKE_customerOrdeno");
					filterParams.put("LIKE_fromno", ordeno);
					ediOrders=this.ediOrderService.crTimeHoursLists(filterParams);
					if(ediOrders.isEmpty()){
						throw new Exception("订单号："+ordeno+"不存在");
					}else if(ediOrders.size()>1){
						throw new Exception("订单号："+ordeno+" 客户："+customerCode+"数据异常");
					}else{
						e=ediOrders.get(0);
					}
				}else if(ediOrders.size()>1){
					throw new Exception("订单号："+ordeno+" 客户："+customerCode+"数据异常");
				}else{
					e=ediOrders.get(0);
				}
			}else if(ediOrders.size()>1){
				throw new Exception("订单号："+ordeno+" 客户："+customerCode+"数据异常");
			}else{
				e=ediOrders.get(0);
			}
			
			log.info("开始取消订单---订单号:"+ordeno+"====客户:"+customers.getCustomerName());
			if ("cancel".equals(e.getOrderStatus())) {
				log.error(ordeno + ":该订单号已经取消");
				throw new Exception(ordeno + ":该订单号已经取消");
			}
			e.setOrderStatus("cancel");// 设置取消订单		
			//SaveEdiOrdenoRedis.saveRedis(redisEdiOrdenoService, e);
		
			 //如果是限制订单流入的商家，消除订单预定数量
			 Customers customer=this.customersDao.findByCustomerCode(customerCode);
			 if("1".equals(customer.getPlaceStatus())){ //限制订单流入的商家
				
				if(!(e.getBackupTaskCode()!=null)){
					//遍历订单，将订单的sku需求整理为：map<sku,num>格式 
					Map<String, Integer> map=new HashMap<String, Integer>();
				
						List<EdiOrderItem> itemList=this.ediOrderItemDao.findByOrdeno(e.getOrdeno());
						for (EdiOrderItem item : itemList) {
							String sku=item.getSku();
							int qty=item.getQty();
							if(map.keySet().contains(sku)){
								map.put(sku, map.get(sku)+qty);
							}else{
								map.put(sku, qty);
							}
						}
				
					 
					for(String sku: map.keySet()){
						int qty=map.get(sku);
						CusStockMerge merge=this.cusStockMergeDao.findCustomerWarSku(customerCode, e.getWarehouseCode(), sku);
						if(merge!=null){
							int _orderNum=merge.getOrderNum();
							int temp=_orderNum-qty;
							if (temp < 0) {
								log.error("预定库存异常，sku:"+sku+" ; 商家："+e.getCustomerCode()+" ; 仓库："+e.getWarehouseCode());
							}
							merge.setOrderNum(Math.max(temp,0));
							this.cusStockMergeDao.save(merge);
							
						}
					} 
				}
				
			 }
			
			ediOrderDao.save(e);
			
			//创建取消单登记信息
			ExceptionOrder eOrder=new ExceptionOrder();
			eOrder.setExceptionType("cancel");
			eOrder.setRecallFlag("unrecall");
			eOrder.setCreaterUuid(jobuuid);
			eOrder.setCreateTime(new Date());
			eOrder.setOrderno(ordeno);
			eOrder.setCustomerCode(e.getCustomerCode());
			this.exceptionOrderDao.save(eOrder);
			log.info("修改订单号"+ordeno+"状态成功cancel:");
			BackupTaskOrdeno backupTaskOrdeno = backupTaskOrdenoDao.findOrdeno(customerCode, ordeno);
			if (backupTaskOrdeno == null) {// 表明该订单还没有分配分拣批次
				log.info(ordeno+":订单号没有分配分拣批次");
				return;
			}
			// 生成了分拣批次但是没有生成拣货批次
			if (backupTaskOrdeno.getBackupTaskCode() == null) {
				List<BackupTaskOrdeno> bs=backupTaskOrdenoDao.findByBatchTaskCode(backupTaskOrdeno.getBatchTaskCode());
				if(bs.size()==1){
					BatchTask batchTask =batchTaskDao.findByBatchTaskCode(backupTaskOrdeno.getBatchTaskCode());
					batchTaskDao.delete(batchTask);
					log.info(ordeno+":订单号所属的分拣批次只有一个订单");
				}
				backupTaskOrdenoDao.delete(backupTaskOrdeno);
				log.info(ordeno+":订单号分配了分拣批次但是没有生成分拣任务");
				return;
			}

			BackupTask backupTask = backupTaskDao.findByBackupTaskCode(backupTaskOrdeno.getBackupTaskCode());// 拣货任务
			ShippedBatch shippedBatch = shippedBatchDao.findByBackupTaskCode(backupTask.getBackupTaskCode());// 出库批次
			BatchTask batchTask = batchTaskDao.findByBatchTaskCode(backupTask.getBatchTaskCode());// 分拣批次
			List<EdiOrderItem> ediOrderItems = ediOrderItemDao.findByCustomerCodeAndOrdeno(customerCode, ordeno);// 订单商品信息
			Map<String, Integer> maps = getMaps(ediOrderItems);
			Set<String> values = maps.keySet();
			log.info("该订单的商品信息为:"+maps);
			//处理wms拣货流程
			if(backupTask!=null){
				//生成分拣拣货后，完成拣货任务前，并且是减库存
				if(!"finish".equals(backupTask.getPickStatus())&&"1".equals(customers.getSubStock())){
					//处理订单占用库存
					this.updateStock(backupTaskOrdeno, customerCode, e.getWarehouseCode());
				}
				
				
				for (String key : values) {
					List<WorkTaskItem> workTaskItems=this.workTaskItemDao.findByTaskCodeAndSku(backupTask.getBackupTaskCode(), key);
					int value = maps.get(key);
					for(WorkTaskItem wti:workTaskItems){
						int num=wti.getNum();
						if(num>value){
							wti.setNum(num-value);
							if(wti.getNum().equals(wti.getPickedNum())){
								wti.setPickStatus("picked");
							}
							this.workTaskItemDao.save(wti);
							break;
						}else if(num==value){
							this.workTaskItemDao.delete(wti);
							break;
						}else{
							this.workTaskItemDao.delete(wti);
							value=value-num;
						}
					}
				}
			}
			int skuQty = 0;
			for (String key : values) {
		
				// 根据拣货任务号与商品编码查询商品拣货信息
				BackupTaskSku backupTaskSku = backupTaskSkuDao.findByBackupTaskCodeAndSkuId(backupTaskOrdeno.getBackupTaskCode(), key);
				int value = maps.get(key);
				log.info("开始遍历商品编号:"+key+"====数量:"+value);
				skuQty += value;
				int index = backupTaskSku.getRealQty() - value;
				log.info("拣货任务里面该商品商量为:"+backupTaskSku.getRealQty());
				log.info("删除该订单后拣货任务所需该商品数量为:"+index);
				//处理箱子信息
				if (shippedBatch != null) {
					log.info("出库批次编号不为空");
					List<ShippedBoxSkus> shippedBoxSkus = shippedBoxSkusDao.findByBatchCodeAndSkuId(shippedBatch.getBatchCode(), key);
					if (!shippedBoxSkus.isEmpty()) {
					    log.info("该出库批次已经有商品扫描装箱");
						int pendNumber=backupTaskSku.getRealQty()-backupTaskSku.getCheckQty();//未拣货数量
						if(pendNumber>=0){//该商品全部拣货完成
							if(pendNumber<value){
								int tempValue=value-pendNumber;
								ShippedBoxSkus s = getShippedBoxSkus(shippedBoxSkus, tempValue);
								if (s != null) {
									String boxCode=s.getBoxCode();
									log.info("已经装箱的商品中有一个箱子的商品能满足该取消单的商品信息");
									int temp = s.getRealQty() - tempValue;
									if (temp == 0) {
										boxSkus(s,shippedBatch);
									} else {
										s.setRealQty(temp);
										shippedBoxSkusDao.save(s);
									}
									setShippedBox(boxCode);
								} else {
									setShippedBoxSkus(shippedBoxSkus, tempValue,shippedBatch);
								}
							}							
						}else{
							throw new Exception("商品拣货数量不正确");
						}
					}
				}
				
				if (index == 0) {
					log.info("该商品拣货任务中的数量与取消单商品数量一致");
					List<BackupTaskSku> BackupTaskSkus = backupTaskSkuDao.findByBackupTaskCode(backupTaskOrdeno.getBackupTaskCode());
					// 该拣货批次只有一条拣货sku
					if (BackupTaskSkus.size() == 1) {
						log.info("该拣货任务只有一条拣货sku");
						// 该分拣批次只有一条拣货任务
						List<BackupTask> backupTasks = backupTaskDao.findByBatchTaskCode(backupTask.getBatchTaskCode());
						if (backupTasks.size() == 1) {
							log.info("删除生成的分拣批次");
							batchTaskDao.delete(batchTask);// 删除该拣货任务
							batchTask=null;
						} else {
							if (batchTask.getSkuType() > 0) {
								batchTask.setSkuType(batchTask.getSkuType() - 1);
							}
						}
						if (shippedBatch != null) {
							log.info("删除该出库批次:"+backupTask.getBatchCode());
							shippedBatchDao.delete(backupTask.getBatchCode());// 删除该拣货出库批次
							log.info("删除该出库批次箱子列表:"+backupTask.getBatchCode());
							shippedBoxDao.delete(backupTask.getBatchCode());
							log.info("删除该出库批次箱子商品列表:"+backupTask.getBatchCode());
							shippedBoxSkusDao.delete(backupTask.getBatchCode());
							log.info("删除该出库批次箱子订单列表:"+backupTask.getBatchCode());
							shippedBoxOrdenoDao.delete(backupTask.getBatchCode());
							shippedBatch = null;
						}
						log.info("删除该拣货任务:");
						backupTaskDao.delete(backupTask);
						backupTask=null;
					} else {
						backupTask.setSkuQty(backupTask.getSkuQty()-value);
						backupTask.setSkuType(backupTask.getSkuType() - 1);
						if (shippedBatch != null) {
							shippedBatch.setSkuType(shippedBatch.getSkuType() - 1);
						}
					}
					log.info("删除该拣货任务商品列表:"+backupTaskSku.getBackupTaskCode());
					backupTaskSkuDao.delete(backupTaskSku);
				} else if (index > 0) {
					log.info("该商品拣货任务中的商品数量大于取消单所包含的的商品数量");
					backupTask.setSkuQty(backupTask.getSkuQty()-value);
					if("finish".equals(backupTaskSku.getStatus())){//该商品已经拣货完成
						backupTaskSku.setRealQty(index);
						backupTaskSku.setCheckQty(index);
					}else{
						if(index<=backupTaskSku.getCheckQty()){
							backupTaskSku.setRealQty(index);
							backupTaskSku.setCheckQty(index);
							backupTaskSku.setStatus("finish");
						}else{
							backupTaskSku.setRealQty(index);
						}
					}
					backupTaskSkuDao.save(backupTaskSku);
				} else {
					log.error("商品数量不正确");
					throw new Exception(key + ":商品数量不正确！");
				}
				
			}
			// 判断是否拣货完毕
			if (shippedBatch != null) {
				shippedBatch.setOrdenoQty(shippedBatch.getOrdenoQty() - 1);
				shippedBatch.setSkuQty(shippedBatch.getSkuQty() - skuQty);
				shippedBatchDao.save(shippedBatch);

				// 该出库批次已经推向TMS
				if ("finish".equals(shippedBatch.getStatus())) {
					String result = null;
					try {
						result = HttpPost.bmsCancelOrdeno(customers, ordeno);
						log.info("TMS返回的结果为:" + result);
					} catch (Exception e1) {
						log.error("TMS取消接口异常", e1);
					}
				}
			}
			if(backupTask!=null){
				backupTask.setOrdenoQty(backupTask.getOrdenoQty() - 1);
				backupTaskDao.save(backupTask);
			}
			
			if(batchTask!=null){
				batchTask.setOrdenoQty(batchTask.getOrdenoQty() - 1);
				batchTaskDao.save(batchTask);
			}
			backupTaskOrdenoDao.delete(backupTaskOrdeno);
		} catch (Exception e1) {
			
			throw e1;
		}
	}
	

	/**
	 * 取消订单方法
	 * 
	 * @param ordeno
	 *            淘宝订单号或者商家订单号
	 * @throws Exception
	 */
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	public void cancelOrdenoOld(String ordeno, String customerCode,String jobuuid)throws Exception {
		try {
			Customers customers=this.customersDao.findByCustomerCode(customerCode);
			log.info("开始取消订单---订单号:"+ordeno+"====客户:"+customers.getCustomerName());
			List<EdiOrder> orderList = ediOrderDao.findByCustomerCodeAndCustomerOrdeno(customerCode,ordeno);
			EdiOrder e = orderList.isEmpty() ? null : orderList.get(0);
			if (e == null) {
				orderList = ediOrderDao.findByCustomerCodeAndFromno(customerCode,ordeno);
				e = orderList.isEmpty() ? null : orderList.get(0);
				if (e == null) {
					e=ediOrderDao.findByOrdeno(ordeno);
					if(e==null){
						log.error(ordeno + ":该订单号不存在!");
						throw new Exception(ordeno + ":该订单号不存在!");
					}
				}
				
			}
			ordeno = e.getOrdeno();
			if ("cancel".equals(e.getOrderStatus())) {
				log.error(ordeno + ":该订单号已经取消");
				throw new Exception(ordeno + ":该订单号已经取消");
			}
			
			
			 //如果是限制订单流入的商家，消除订单预定数量
			 Customers customer=this.customersDao.findByCustomerCode(customerCode);
			 if("1".equals(customer.getPlaceStatus())){ //限制订单流入的商家
				
				if(!(e.getBackupTaskCode()!=null)){
					//遍历订单，将订单的sku需求整理为：map<sku,num>格式 
					Map<String, Integer> map=new HashMap<String, Integer>();
				
						List<EdiOrderItem> itemList=this.ediOrderItemDao.findByOrdeno(e.getOrdeno());
						for (EdiOrderItem item : itemList) {
							String sku=item.getSku();
							int qty=item.getQty();
							if(map.keySet().contains(sku)){
								map.put(sku, map.get(sku)+qty);
							}else{
								map.put(sku, qty);
							}
						}
				
					 
					for(String sku: map.keySet()){
						int qty=map.get(sku);
						CusStockMerge merge=this.cusStockMergeDao.findCustomerWarSku(customerCode, e.getWarehouseCode(), sku);
						if(merge!=null){
							int _orderNum=merge.getOrderNum();
							int temp=Math.max(_orderNum-qty,0);
							merge.setOrderNum(temp);
							this.cusStockMergeDao.save(merge);
							if (temp < 0) {
								log.error("预定库存异常，sku:"+sku+" ; 商家："+e.getCustomerCode()+" ; 仓库："+e.getWarehouseCode());
							}
							
						}
					} 
				}
				
			 }
			
			e.setOrderStatus("cancel");// 设置取消订单
			
			//SaveEdiOrdenoRedis.saveRedis(redisEdiOrdenoService, e);
		
			ediOrderDao.save(e);
			
			//创建取消单登记信息
			ExceptionOrder eOrder=new ExceptionOrder();
			eOrder.setExceptionType("cancel");
			eOrder.setRecallFlag("unrecall");
			eOrder.setCreaterUuid(jobuuid);
			eOrder.setCreateTime(new Date());
			eOrder.setOrderno(ordeno);
			eOrder.setCustomerCode(e.getCustomerCode());
			this.exceptionOrderDao.save(eOrder);
			
			log.info("修改订单号"+ordeno+"状态成功cancel:");
			BackupTaskOrdeno backupTaskOrdeno = backupTaskOrdenoDao.findOrdeno(customerCode, ordeno);
			if (backupTaskOrdeno == null) {// 表明该订单还没有分配分拣批次
				log.info(ordeno+":订单号没有分配分拣批次");
				return;
			}
			// 生成了分拣批次但是没有生成拣货批次
			if (backupTaskOrdeno.getBackupTaskCode() == null) {
				List<BackupTaskOrdeno> bs=backupTaskOrdenoDao.findByBatchTaskCode(backupTaskOrdeno.getBatchTaskCode());
				if(bs.size()==1){
					BatchTask batchTask =batchTaskDao.findByBatchTaskCode(backupTaskOrdeno.getBatchTaskCode());
					batchTaskDao.delete(batchTask);
					log.info(ordeno+":订单号所属的分拣批次只有一个订单");
				}
				backupTaskOrdenoDao.delete(backupTaskOrdeno);
				log.info(ordeno+":订单号分配了分拣批次但是没有生成分拣任务");
				return;
			}

			BackupTask backupTask = backupTaskDao.findByBackupTaskCode(backupTaskOrdeno.getBackupTaskCode());// 拣货任务
			ShippedBatch shippedBatch = shippedBatchDao.findByBackupTaskCode(backupTask.getBackupTaskCode());// 出库批次
			BatchTask batchTask = batchTaskDao.findByBatchTaskCode(backupTask.getBatchTaskCode());// 分拣批次
			List<EdiOrderItem> ediOrderItems = ediOrderItemDao.findByCustomerCodeAndOrdeno(customerCode, ordeno);// 订单商品信息
			Map<String, Integer> maps = getMaps(ediOrderItems);
			Set<String> values = maps.keySet();
			log.info("该订单的商品信息为:"+maps);
			int skuQty = 0;
			for (String key : values) {
				// 根据拣货任务号与商品编码查询商品拣货信息
				BackupTaskSku backupTaskSku = backupTaskSkuDao.findByBackupTaskCodeAndSkuId(backupTaskOrdeno.getBackupTaskCode(), key);
				int value = maps.get(key);
				log.info("开始遍历商品编号:"+key+"====数量:"+value);
				skuQty += value;
				int index = backupTaskSku.getRealQty() - value;
				log.info("拣货任务里面该商品商量为:"+backupTaskSku.getRealQty());
				log.info("删除该订单后拣货任务所需该商品数量为:"+index);
				//处理箱子信息
				if (shippedBatch != null) {
					log.info("出库批次编号不为空");
					List<ShippedBoxSkus> shippedBoxSkus = shippedBoxSkusDao.findByBatchCodeAndSkuId(shippedBatch.getBatchCode(), key);
					if (!shippedBoxSkus.isEmpty()) {
					    log.info("该出库批次已经有商品装箱");
						int pendNumber=backupTaskSku.getRealQty()-backupTaskSku.getCheckQty();//未拣货数量
						if(pendNumber>=0){//该商品全部拣货完成
							if(pendNumber<value){
								int tempValue=value-pendNumber;
								ShippedBoxSkus s = getShippedBoxSkus(shippedBoxSkus, tempValue);
								if (s != null) {
									String boxCode=s.getBoxCode();
									log.info("已经装箱的商品中有一个箱子的商品能满足该取消单的商品信息");
									int temp = s.getRealQty() - tempValue;
									if (temp == 0) {
										boxSkus(s,shippedBatch);
									} else {
										s.setRealQty(temp);
										shippedBoxSkusDao.save(s);
									}
									setShippedBox(boxCode);
								} else {
									setShippedBoxSkus(shippedBoxSkus, tempValue,shippedBatch);
								}
								
							}
							
						}else{
							throw new Exception("商品拣货数量不正确");
						}
							
					}
				}
				
				if (index == 0) {
					log.info("该商品拣货任务中的数量与取消单商品数量一致");
					List<BackupTaskSku> BackupTaskSkus = backupTaskSkuDao.findByBackupTaskCode(backupTaskOrdeno.getBackupTaskCode());
					// 该拣货批次只有一条拣货sku
					if (BackupTaskSkus.size() == 1) {
						log.info("该拣货任务只有一条拣货sku");
						// 该分拣批次只有一条拣货任务
						List<BackupTask> backupTasks = backupTaskDao.findByBatchTaskCode(backupTask.getBatchTaskCode());
						if (backupTasks.size() == 1) {
							log.info("删除生成的分拣批次");
							batchTaskDao.delete(batchTask);// 删除该拣货任务
							batchTask=null;
						} else {
							if (batchTask.getSkuType() > 0) {
								batchTask.setSkuType(batchTask.getSkuType() - 1);
							}
						}
						if (shippedBatch != null) {
							log.info("删除该出库批次:"+backupTask.getBatchCode());
							shippedBatchDao.delete(backupTask.getBatchCode());// 删除该拣货出库批次
							log.info("删除该出库批次箱子列表:"+backupTask.getBatchCode());
							shippedBoxDao.delete(backupTask.getBatchCode());
							log.info("删除该出库批次箱子商品列表:"+backupTask.getBatchCode());
							shippedBoxSkusDao.delete(backupTask.getBatchCode());
							log.info("删除该出库批次箱子订单列表:"+backupTask.getBatchCode());
							shippedBoxOrdenoDao.delete(backupTask.getBatchCode());
							shippedBatch = null;
						}
						log.info("删除该拣货任务:");
						backupTaskDao.delete(backupTask);
						backupTask=null;
					} else {
						backupTask.setSkuQty(backupTask.getSkuQty()-value);
						backupTask.setSkuType(backupTask.getSkuType() - 1);
						if (shippedBatch != null) {
							shippedBatch.setSkuType(shippedBatch.getSkuType() - 1);
						}
					}
					log.info("删除该拣货任务商品列表:"+backupTaskSku.getBackupTaskCode());
					backupTaskSkuDao.delete(backupTaskSku);
				} else if (index > 0) {
					log.info("该商品拣货任务中的商品数量大于取消单所包含的的商品数量");
					backupTask.setSkuQty(backupTask.getSkuQty()-value);
					if("finish".equals(backupTaskSku.getStatus())){//该商品已经拣货完成
						backupTaskSku.setRealQty(index);
						backupTaskSku.setCheckQty(index);
					}else{
						if(index<=backupTaskSku.getCheckQty()){
							backupTaskSku.setRealQty(index);
							backupTaskSku.setCheckQty(index);
							backupTaskSku.setStatus("finish");
						}else{
							backupTaskSku.setRealQty(index);
						}
					}
					backupTaskSkuDao.save(backupTaskSku);
				} else {
					log.error("商品数量不正确");
					throw new Exception(key + ":商品数量不正确！");
				}
				
			}
			// 判断时候拣货完毕
			if (shippedBatch != null) {
				shippedBatch.setOrdenoQty(shippedBatch.getOrdenoQty() - 1);
				shippedBatch.setSkuQty(shippedBatch.getSkuQty() - skuQty);
				shippedBatchDao.save(shippedBatch);

				// 该出库批次已经推向TMS
				if ("finish".equals(shippedBatch.getStatus())) {
					String result = null;
					try {
						result = HttpPost.bmsCancelOrdeno(customers, ordeno);
						log.info("TMS返回的结果为:" + result);
					} catch (Exception e1) {
						log.error("TMS取消接口异常", e1);

					}
				}
			}
			if(backupTask!=null){
				backupTask.setOrdenoQty(backupTask.getOrdenoQty() - 1);
				backupTaskDao.save(backupTask);

			}
			
			if(batchTask!=null){
				batchTask.setOrdenoQty(batchTask.getOrdenoQty() - 1);
				batchTaskDao.save(batchTask);

			}
			backupTaskOrdenoDao.delete(backupTaskOrdeno);
		} catch (Exception e) {
			
			throw e;
		}
	}
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	private void boxSkus(ShippedBoxSkus s,ShippedBatch shippedBatch) throws Exception {
		try {
			List<ShippedBoxSkus> ss = shippedBoxSkusDao.findByBoxCode(s.getBoxCode());
			if (ss.size() == 1) {
				shippedBoxDao.deleteBoxCode(s.getBoxCode());
				shippedBatch.setBoxQty(shippedBatch.getBoxQty()-1);
				shippedBatchDao.save(shippedBatch);
				
			}
			shippedBoxSkusDao.delete(s);

		} catch (Exception e) {
			throw e;
		}
	}
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	private void setShippedBoxSkus(List<ShippedBoxSkus> shippedBoxSkus,int skuQty,ShippedBatch shippedBatch) throws Exception {
		try {
			for (ShippedBoxSkus s : shippedBoxSkus) {
				String boxCode=s.getBoxCode();
				int temp = s.getRealQty() - skuQty;
				if (temp > 0) {
					s.setRealQty(temp);
					shippedBoxSkusDao.save(s);
				} else {
					boxSkus(s,shippedBatch);
					skuQty=skuQty-s.getRealQty();
				}
				if(boxCode==null){
					throw new Exception("订单取消失败箱子还没有封箱");
				}
				setShippedBox(boxCode);
			}
			
		} catch (Exception e) {
			throw e;
		}
	}

	private ShippedBoxSkus getShippedBoxSkus(
			List<ShippedBoxSkus> shippedBoxSkus, int skuQty) throws Exception {
		try {
			for (ShippedBoxSkus s : shippedBoxSkus) {
				if (s.getRealQty() >= skuQty) {
					return s;
				}
			}
			return null;
		} catch (Exception e) {
			throw e;
		}
	}

	private Map<String, Integer> getMaps(List<EdiOrderItem> ediOrderItems)
			throws Exception {
		try {
			Map<String, Integer> maps = new HashMap<String, Integer>();
			for (EdiOrderItem ei : ediOrderItems) {
				if (maps.get(ei.getSku()) == null) {
					maps.put(ei.getSku(), ei.getQty());
				} else {
					maps.put(ei.getSku(), ei.getQty() + maps.get(ei.getSku()));
				}
			}
			return maps;
		} catch (Exception e) {
			throw e;
		}
	}

	public BackupTaskOrdeno findOrdeno(String customerCode, String ordeno) {
		return backupTaskOrdenoDao.findOrdeno(customerCode, ordeno);
	}

	public List<BackupTaskOrdeno> findByBatchCodeAndPickStatus(
			String batchCode, String pickStatus) {
		return backupTaskOrdenoDao.findByBatchCodeAndPickStatus(batchCode,
				pickStatus);
	}

	public List<BackupTaskOrdeno> findByBackupTaskCodeAndStatus(
			String backupTaskCode, String status) {
		return backupTaskOrdenoDao.findByBackupTaskCodeAndStatus(
				backupTaskCode, status);
	}

	public List<BackupTaskOrdeno> findByBackupTaskCode(String backupTaskCode) {
		return backupTaskOrdenoDao.findByBackupTaskCode(backupTaskCode);
	}

	public List<BackupTaskOrdeno> findByBatchCode(String batchCode) {
		return backupTaskOrdenoDao.findByBatchCode(batchCode);
	}

	public BackupTaskOrdeno findByOrdeno(String ordeno) {
		return backupTaskOrdenoDao.findByOrdeno(ordeno);
	}

	@Transactional(readOnly = false)
	public BackupTaskOrdeno save(BackupTaskOrdeno arg0) {
		return backupTaskOrdenoDao.save(arg0);
	}

	@Transactional(readOnly = false)
	public List<BackupTaskOrdeno> save(List<BackupTaskOrdeno> arg0) {
		return (List<BackupTaskOrdeno>) backupTaskOrdenoDao.save(arg0);
	}

	public List<BackupTaskOrdeno> findByBatchTaskCode(String batchTaskCode) {
		return backupTaskOrdenoDao.findByBatchTaskCode(batchTaskCode);
	}

	public List<BackupTaskOrdeno> findByBackupTaskCodeAndBatchTaskCode(
			String backupTaskCode, String batchTaskCode) {
		return backupTaskOrdenoDao.findByBackupTaskCodeAndBatchTaskCode(
				backupTaskCode, batchTaskCode);
	}

	public List<BackupTaskOrdeno> findByBatchCodeAndBatchTaskCode(
			String batchCode, String batchTaskCode) {
		return backupTaskOrdenoDao.findByBatchCodeAndBatchTaskCode(batchCode,
				batchTaskCode);
	}
}
